package com.ruoyi.system.service.impl;

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SM3;
import com.ruoyi.common.utils.SM4;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.bean.BeanValidators;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.system.config.ApiConfig;
import com.ruoyi.system.utils.HttpApi;
import com.ruoyi.system.utils.ListToZipExporter;
import com.ruoyi.system.utils.ParametricTask;
import com.ruoyi.system.utils.TaskScheduler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.system.mapper.SysPhoneRspMapper;
import com.ruoyi.system.domain.SysPhoneRsp;
import com.ruoyi.system.service.ISysPhoneRspService;

import javax.validation.Validator;

/**
 * 中移接口返回Service业务层处理
 * 
 * @author ruoyi
 * @date 2025-03-25
 */
@Service("sysPhoneRspService")
public class SysPhoneRspServiceImpl implements ISysPhoneRspService 
{
    private static final Logger log = LoggerFactory.getLogger(SysFileRspServiceImpl.class);
    @Autowired
    protected Validator validator;
    @Autowired
    private ApiConfig apiConfig;
    @Autowired
    private SysPhoneRspMapper sysPhoneRspMapper;

    /**
     * 查询中移接口返回
     * 
     * @param empowerNo 中移接口返回主键
     * @return 中移接口返回
     */
    @Override
    public SysPhoneRsp selectSysPhoneRspByEmpowerNo(String empowerNo)
    {
        return sysPhoneRspMapper.selectSysPhoneRspByEmpowerNo(empowerNo);
    }

    /**
     * 查询中移接口返回列表
     * 
     * @param sysPhoneRsp 中移接口返回
     * @return 中移接口返回
     */
    @Override
    public List<SysPhoneRsp> selectSysPhoneRspList(SysPhoneRsp sysPhoneRsp)
    {
        return sysPhoneRspMapper.selectSysPhoneRspList(sysPhoneRsp);
    }

    /**
     * 新增中移接口返回
     * 
     * @param sysPhoneRsp 中移接口返回
     * @return 结果
     */
    @Override
    public int insertSysPhoneRsp(SysPhoneRsp sysPhoneRsp)
    {
        return sysPhoneRspMapper.insertSysPhoneRsp(sysPhoneRsp);
    }

    /**
     * 修改中移接口返回
     * 
     * @param sysPhoneRsp 中移接口返回
     * @return 结果
     */
    @Override
    public int updateSysPhoneRsp(SysPhoneRsp sysPhoneRsp)
    {
        return sysPhoneRspMapper.updateSysPhoneRsp(sysPhoneRsp);
    }

    @Override
    public int batchInsertSysPhoneRsps(List<SysPhoneRsp> sysPhoneRsps) {
        return sysPhoneRspMapper.batchInsertSysPhoneRsps(sysPhoneRsps);
    }

    @Override
    public int batchUpdateSysPhoneRsps(List<SysPhoneRsp> sysPhoneRsps) {
        return sysPhoneRspMapper.batchUpdateSysPhoneRsps(sysPhoneRsps);
    }

    /**
     * 批量删除中移接口返回
     * 
     * @param empowerNos 需要删除的中移接口返回主键
     * @return 结果
     */
    @Override
    public int deleteSysPhoneRspByEmpowerNos(String[] empowerNos)
    {
        return sysPhoneRspMapper.deleteSysPhoneRspByEmpowerNos(empowerNos);
    }

    /**
     * 删除中移接口返回信息
     * 
     * @param empowerNo 中移接口返回主键
     * @return 结果
     */
    @Override
    public int deleteSysPhoneRspByEmpowerNo(String empowerNo)
    {
        return sysPhoneRspMapper.deleteSysPhoneRspByEmpowerNo(empowerNo);
    }

    @Override
    public String importPhone(List<SysPhoneRsp> sfs, Long fileId) {

        if (StringUtils.isNull(sfs) || sfs.size() == 0) {
            throw new ServiceException("导入用户数据不能为空！");
        }
        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();

        for (SysPhoneRsp user : sfs) {
            String mobile = user.getMobile();
            try {
                // 验证是否存在这个用户

                if (StringUtils.isNotBlank(mobile)) {
                    BeanValidators.validateWithException(validator, user);

                    SysPhoneRsp sysPhoneRsp = new SysPhoneRsp();
                    sysPhoneRsp.setFileId(fileId);
                    sysPhoneRsp.setMobile(mobile);
                    String empowerNo1 = IdUtils.fastSimpleUUID();
                    sysPhoneRsp.setEmpowerNo(empowerNo1);
                    sysPhoneRsp.setProductCode(apiConfig.getGfyy());
                    String param1 = JSONObject.of("param", JSONObject.of("mobile", SM3.encrypt(mobile),
                            "empowerNo", empowerNo1)).toJSONString();
                    String encrypt1 = SM4.encrypt(param1, apiConfig.getSecretkey());
                    String format1 = String.format("requestRefId=%s&secretId=%s", empowerNo1, apiConfig.getSecretid());
                    String signature1 = SM3.encrypt(format1, apiConfig.getSecretkey());
                    sysPhoneRsp.setRequest(empowerNo1 + "|" + signature1 + "|" + encrypt1);
                    insertSysPhoneRsp(sysPhoneRsp);
                    //
                    SysPhoneRsp phoneRsp = new SysPhoneRsp();
                    phoneRsp.setFileId(fileId);
                    phoneRsp.setMobile(mobile);
                    String empowerNo2 = IdUtils.fastSimpleUUID();
                    phoneRsp.setEmpowerNo(empowerNo2);
                    phoneRsp.setProductCode(apiConfig.getFdcyxjz());
                    String param2 = JSONObject.of("param", JSONObject.of("mobile", SM3.encrypt(mobile),
                            "empowerNo", empowerNo2)).toJSONString();
                    String encrypt2 = SM4.encrypt(param2, apiConfig.getSecretkey());
                    String format2 = String.format("requestRefId=%s&secretId=%s", empowerNo2, apiConfig.getSecretid());
                    String signature2 = SM3.encrypt(format2, apiConfig.getSecretkey());
                    phoneRsp.setRequest(empowerNo2 + "|" + signature2 + "|" + encrypt2);
                    insertSysPhoneRsp(phoneRsp);
                    successNum++;
                    successMsg.append("<br/>" + successNum + "、手机号 " + mobile + " 导入成功");
                } else {
                    failureNum++;
                    failureMsg.append("<br/>" + failureNum + "、手机号 " + mobile + " 为空");
                }
            } catch (Exception e) {
                failureNum++;
                String msg = "<br/>" + failureNum + "、手机号 " + mobile + " 导入失败：";
                failureMsg.append(msg + e.getMessage());
                log.error(msg, e);
            }
        }
        if (failureNum > 0) {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
            throw new ServiceException(failureMsg.toString());
        } else {
            successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：");
        }
        // 请求服务器
        successMsg.append("requestId=" + uploadData(fileId));
        return successMsg.toString();
    }



    @Override
    public String uploadData(Long fileId) {
        SysPhoneRsp sysPhoneRsp = new SysPhoneRsp();
        sysPhoneRsp.setFileId(fileId);
        List<SysPhoneRsp> sysPhoneRsps = selectSysPhoneRspList(sysPhoneRsp);
        Map<String, List<String>> collect = sysPhoneRsps.stream().collect(Collectors.groupingBy(SysPhoneRsp::getProductCode, Collectors.mapping(SysPhoneRsp::getRequest, Collectors.toList())));
        String zipFilePath = null;
        try {
            // 生成请求加密zip
            zipFilePath = FileUploadUtils.getAbsoluteFile(RuoYiConfig.getUploadPath() + File.separator + "zipF", fileId + ".zip").getAbsolutePath();
            ListToZipExporter.exportToZip(collect, zipFilePath);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        String s = IdUtils.fastSimpleUUID();
        String batchResponse = HttpApi.sendBatchSSLApi("batch/submit", s, apiConfig.getSecretid(), apiConfig.getSecretkey(), apiConfig.getUrl(), zipFilePath);
        log.info("batch/submit -> batchResponse:{}", batchResponse);
        JSONObject js1 = JSONObject.parseObject(batchResponse);
        String responseCode = js1.getString("responseCode");
        if ("0000".equals(responseCode)) {
            String requestId = js1.getString("requestId");
            log.info("requestId:{} s:{} equals:{}", requestId, s, s.equals(requestId));
            // 延时队列查询结果
            return getTaskStatus(requestId, fileId);
        } else {
            return batchResponse;
        }
    }

    @Autowired
    private TaskScheduler taskScheduler;

    @Override
    public String getTaskStatus(String requestId, Long fileId) {
        // 查询任务状态
        taskScheduler.submit(new ParametricTask(requestId, fileId), 1, TimeUnit.SECONDS);
        return requestId;
    }

}
